package com.agriculture.competition.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.agriculture.competition.domain.vo.ArrangeVo;
import com.agriculture.competition.domain.vo.ExcelArrangeData;
import com.agriculture.competition.domain.vo.ExcelData;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class ExcelReadUtils {

    @Value("${file.url}")
    private String urlNew;

    @Value("${file.lock}")
    private String lock;


    public ExcelData getExcelData(String url, String tempDir) {
        if ("zeroHourFile".equals(lock)) {
            tempDir = urlNew;
        }
        log.info("ExcelReadUtils.getExcelData:" + url);
        log.info("ExcelReadUtils.getExcelData:" + tempDir);
        ExcelData excelData = null;
        try {
            // 使用File对象检查文件是否存在
            InputStream inputStream = DownloadFile.openConnectionAndGetInputStream(url);
            createDirectoryIfNotExists(tempDir);
            String s = tempDir + File.separator + System.currentTimeMillis() + ".xlsx";
            log.info("ExcelReadUtils.getExcelData===url:" + s);
            File file = new File(s);
            saveInputStreamToFile(inputStream, file);
            ExcelListener listener = new ExcelListener();
            try {
                EasyExcel.read(file, null, listener).sheet().doRead();
            } catch (Exception e) {
                log.error("Error reading Excel file: " + e.getMessage());
                e.printStackTrace();
            }
            // 获取并打印数据
            List<Map<Integer, String>> dataList = listener.getDataList();
            excelData = new ExcelData();
            excelData.setDataList(dataList);
            excelData.setHeadMap(listener.getHeadMap());
        } catch (Exception e) {
            log.error("getExcelData", e);
        } finally {
            deleteFile(new File(tempDir));
        }
        return excelData;
    }

    public static void createDirectoryIfNotExists(String dirPath) {
        Path path = Paths.get(dirPath);
        if (!Files.exists(path)) {
            try {
                Files.createDirectories(path);
                System.out.println("Created directory: " + dirPath);
            } catch (IOException e) {
                System.err.println("Failed to create directory: " + dirPath);
                log.error("createDirectoryIfNotExists", e);
            }
        } else {
            System.out.println("Directory already exists: " + dirPath);
        }
    }

    public static void deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
            throw new RuntimeException("文件删除失败,请检查文件路径是否正确");
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f : files) {
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()) {
                deleteFile(f);
            } else {
                f.delete();
            }
        }
    }

    /**
     * @param url
     * @param title        选中的excel标题
     * @param timeTitleStr 时间excel对应的中文
     * @param begin        开始时间 yyyy
     * @param end          结束时间 yyyy
     * @return
     */
    public ExcelArrangeData getExcelDataByTitle(String url, String title, String timeTitleStr, String begin, String end, String tempDir) {
        ExcelArrangeData excelArrangeData = null;
        try {
            excelArrangeData = new ExcelArrangeData();
            List<ArrangeVo> arrangeVoList = new ArrayList<>();
            InputStream inputStream = DownloadFile.openConnectionAndGetInputStream(url);

            if ("zeroHourFile".equals(lock)) {
                tempDir = urlNew;
            }
            log.info("ExcelReadUtils.getExcelDataByTitle:" + url);
            log.info("ExcelReadUtils.getExcelDataByTitle:" + tempDir);
            createDirectoryIfNotExists(tempDir);
            File file = new File(tempDir + File.separator + System.currentTimeMillis() + ".xlsx");
            saveInputStreamToFile(inputStream, file);
            ExcelListener listener = new ExcelListener();
            try {
                EasyExcel.read(file, null, listener).sheet().doRead();
            } catch (Exception e) {
                log.error("Error reading Excel file: " + e.getMessage());
                e.printStackTrace();
            }
            // 获取并打印数据
            List<Map<Integer, String>> dataList = listener.getDataList();
            Map<Integer, String> headMap = listener.getHeadMap();
            Integer index = 0;
            Integer timeTitle = 0;
            if (headMap != null) {
                for (Integer key : headMap.keySet()) {
                    String title1 = headMap.get(key);
                    if (StringUtils.equals(title1, title)) {
                        index = key;
                    }
                    if (StringUtils.equals(title1, timeTitleStr)) {
                        timeTitle = key;
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(dataList)) {
                for (Map<Integer, String> map : dataList) {
                    ArrangeVo arrangeVo = new ArrangeVo();
                    arrangeVo.setTitle(title);
                    if (map.containsKey(index)) {
                        arrangeVo.setValue(map.get(index));
                    }
                    if (map.containsKey(timeTitle)) {
                        String s = map.get(timeTitle);
                        if (StringUtils.isNotBlank(s)) {
                            if (s.contains("年")) {
                                String year = s.replaceAll("年", "");
                                arrangeVo.setTime(year);
                            } else {
                                arrangeVo.setTime(s);
                            }
                        }
                    }
                    arrangeVoList.add(arrangeVo);
                }
            }
            if (CollectionUtil.isNotEmpty(arrangeVoList)) {
                arrangeVoList.sort(Comparator.comparing(ArrangeVo::getTime, Comparator.nullsLast(Comparator.reverseOrder())));
                if (StringUtils.isNotBlank(begin) && StringUtils.isNotBlank(end)) {
                    List<ArrangeVo> collect = arrangeVoList.stream().filter(user -> {
                        int userYear = Integer.parseInt(user.getTime());
                        int begin1 = Integer.parseInt(begin);
                        int end1 = Integer.parseInt(end);
                        return userYear >= begin1 && userYear <= end1;
                    }).collect(Collectors.toList());
                    excelArrangeData.setArrangeVoList(collect);
                } else {
                    excelArrangeData.setArrangeVoList(arrangeVoList);
                }
            }
            excelArrangeData.setTitle(title);
        } catch (Exception e) {
            log.error("getExcelDataByTitle", e);
        } finally {
            deleteFile(new File(tempDir));
        }
        return excelArrangeData;
    }

    public static void saveInputStreamToFile(InputStream inputStream, File file) throws IOException {
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            System.out.println("数据已成功写入文件: " + file.getAbsolutePath());
        } catch (Exception e) {
            log.error("saveInputStreamToFile", e);
        }
    }

    public static InputStream downloadFile(String fileUrl) throws Exception {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(fileUrl)
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            return response.body().byteStream();
        }
    }
}

@Slf4j
class ExcelListener extends AnalysisEventListener<Map<Integer, String>> {
    private final List<Map<Integer, String>> dataList = new ArrayList<>();
    private Map<Integer, String> headMap;

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 处理表头信息（如果需要）
        log.info("Header: " + headMap);
        this.headMap = headMap;
    }

    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) {
        dataList.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("Data read completed.");
    }

    public List<Map<Integer, String>> getDataList() {
        return dataList;
    }

    public Map<Integer, String> getHeadMap() {
        return headMap;
    }


}
